package com.adee.gulimall.product.service.impl;

import com.adee.gulimall.common.utils.PageUtils;
import com.adee.gulimall.common.utils.Query;
import com.adee.gulimall.product.dao.CategoryDao;
import com.adee.gulimall.product.entity.CategoryEntity;
import com.adee.gulimall.product.service.CategoryBrandRelationService;
import com.adee.gulimall.product.service.CategoryService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@CacheConfig(cacheNames = "my-redis-cache1", cacheManager = "redisCacheManager")
@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
    @Autowired
    private CategoryBrandRelationService categoryBrandRelationService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String key = (String)params.get("key");
        QueryWrapper<CategoryEntity> wrapper = new QueryWrapper<>();
        if(!StringUtils.isEmpty(key)) {
            wrapper.eq("cat_id", key).or().like("name", key);
        }
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }


    // @Cacheable(value = {"category"},key = "#root.method.name")
    @Cacheable(value = {"category"},key = "'listWithTree'")
    @Override
    public List<CategoryEntity> listWithTree() {
        // 查询所有商品分类
        QueryWrapper<CategoryEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("show_status", 1);
        List<CategoryEntity> list = baseMapper.selectList(wrapper);
        // 处理为树形结构
        List<CategoryEntity> level1 = new ArrayList<>();
        List<CategoryEntity> level2 = new ArrayList<>();
        List<CategoryEntity> level3 = new ArrayList<>();
        // 辅助map，加快查询
        HashMap<Long, CategoryEntity> map1 = new HashMap<>();
        HashMap<Long, CategoryEntity> map2 = new HashMap<>();
        list.stream().forEach(item -> {
            Integer lv = item.getCatLevel();
            if(lv == 1) {
                level1.add(item);
                map1.put(item.getCatId(), item);
            } else if(lv == 2) {
                level2.add(item);
                map2.put(item.getCatId(), item);
            } else if(lv == 3) {
                level3.add(item);
            }
            if(item.getSort() == null) {
                item.setSort(0);
            }
        });
        level3.forEach(item -> {
            CategoryEntity parent = map2.get(item.getParentCid());
            if(parent != null) {
                if(parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(item);
            } else {
                log.warn("menu has no parent： " + item.toString());
            }
        });
        level2.forEach(item -> {
            CategoryEntity parent = map1.get(item.getParentCid());
            if(parent != null) {
                if(parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(item);
            } else {
                log.warn("menu has no parent： " + item.toString());
            }
        });
        level1.sort((a, b) -> a.getSort() -b.getSort());
        level1.forEach(item -> {
            List<CategoryEntity> children = item.getChildren();
            if(children != null) {
                children.sort((a, b) -> a.getSort() -b.getSort());
                children.forEach(item2 -> {
                    List<CategoryEntity> children2 = item2.getChildren();
                    if(children2 != null) {
                        children2.sort((a, b) -> a.getSort() -b.getSort());
                    }
                });
            }
        });
        return level1;
    }

    @Override
    public Long[] getCategoryPath(Long catId) {
        Map<String, Long> map = getBaseMapper().getCategoryPath(catId);
        Long[] arr = new Long[3];
        arr[0] = map.get("ppid");
        arr[1] = map.get("pid");
        arr[2] = catId;
        return arr;
    }

    @Transactional
    @Override
    public void updateDetails(CategoryEntity category) {
        this.updateById(category);
        if(!StringUtils.isEmpty(category.getName())) {
            categoryBrandRelationService.updateCategory(category.getCatId(), category.getName());
        }
    }

    @Override
    public List<CategoryEntity> getLevel1Categories() {
        QueryWrapper<CategoryEntity> wrapper = new QueryWrapper<CategoryEntity>().eq("cat_level", 1);
        List<CategoryEntity> list = this.list(wrapper);
        return list;
    }

}